Repository navigation
Feat/lock simulation - #1
Merged
Merged
Conversation
Add package.json description/keywords/repository for the public Webvoltz profile listing, commit the ESLint/Prettier/Husky/commitlint/ Gitleaks tooling baseline, and remove unused Vite/React starter assets (react.svg, default vite.svg favicon replaced with a project favicon).
Bump react, zustand, tailwindcss, vite, eslint, and typescript-eslint to their latest versions within existing semver ranges. Clears all 40 pnpm audit advisories (28 high, 10 moderate, 2 low) that were pinned in the lockfile against older transitive resolutions.
Replace the two alert() call sites (8-seat cap, fake payment redirect) with controlled UI state: seatStore now exposes an aria-live feedback message rendered by a new Toast component, and BookingSummary shows an inline confirmation panel instead of blocking on a browser dialog.
Configure Vitest with jsdom + Testing Library and cover the core booking flows: seat selection/deselection, the 8-seat cap surfacing feedback instead of alert(), clearing the selection, the persisted- seats localStorage round trip, and arrow-key/Enter/Space keyboard navigation across rows including skipping unavailable seats.
Add GitHub Actions pipeline running on every push/PR: install (frozen lockfile), quality (format-check + lint + typecheck), test, build, plus a full-history Gitleaks secret scan and commitlint on the commit range being merged.
Add the problem statement, 15,000+ seat rendering notes (section- level SVG collapsing), the case for SVG over canvas/WebGL, the Zustand persistence strategy, accessibility notes, and a Mermaid architecture diagram to the README, plus docs/engineering-notes.md covering the tradeoffs and remaining performance bottlenecks in detail.
actions/checkout@v4, actions/setup-node@v4, and pnpm/action-setup@v4 still run on the Node.js 20 runtime, which GitHub Actions now flags as deprecated. Bump each to its v5 major, where all three switched to Node.js 24.
- Add Booking History: past purchases list, click a booking to highlight its seats on the map - Make the sidebar responsive: full-screen drawer below 1024px, persistent panel above it - Pin Total/Proceed to Pay outside the scroll area so it stays reachable with many seats picked - Add a confirm dialog before clearing selected seats, replacing the instant clear action - Trap focus behind open drawers/dialogs so keyboard users can't reach hidden controls - Add page title/description, robots.txt, and llms.txt for search engines and AI crawlers - Remove unused Stage/SectionSkeleton components and refresh generated sample data - Update and extend tests to cover booking history and the new store actions
- Upgraded ESLint to strictTypeChecked + stylisticTypeChecked with the full required rule set — this surfaced and fixed real bugs: a missing-return path in Section.tsx, unsafe DOM element casts in Seat.tsx (now properly typed with SVGGElement generics), and blind JSON.parse/fetch().json() casts in seatStore.ts/useVenue.ts replaced with real runtime type guards instead of trusting the data - Added missing tsconfig strictness options (noImplicitReturns, noImplicitOverride, forceConsistentCasingInFileNames, noPropertyAccessFromIndexSignature, allowUnreachableCode, allowUnusedLabels) - Pre-commit hook now runs the full quality check and production build, not just lint-staged - Commitlint header/body/footer limits relaxed to 1000 chars, matching the org standard - Every dependency pinned to an exact version; added a security:audit script - Added .nvmrc/.npmrc, a packageManager field, and aligned CI's pnpm version (10 → 11) to match what's actually installed — this was a real, previously-undocumented mismatch - Enabled test coverage reporting (V8) with thresholds set as a floor against regression — still well below the org standard's targets, tracked honestly in engineering-notes.md - Fixed stale doc references pointing at BookingSummary.tsx that should've said SeatSelectionFooter.tsx
The seating map used to zoom by resizing the SVG's own width/height and pan by relying on the browser's native scrollbars, which made it impossible to keep any point stationary while zooming and gave no way to intercept trackpad pinch gestures (they just triggered the browser's own page zoom). Replace it with a single CSS transform (translate + scale) driven by `zoom`/`pan` state in the store: - utils/viewTransform.ts: pure, unit-tested math for fit-to-viewport zoom, pan clamping, and re-anchoring pan/zoom around a pointer so the content under the cursor stays put while zooming. - VenueMap now renders the map inside a transformed wrapper instead of resizing the SVG element itself. - App.tsx anchors zoom-in/out buttons on the viewport center, and adds a native wheel listener so ctrl/cmd+wheel (how browsers report trackpad pinch) zooms toward the pointer while a plain wheel/scroll pans. Panning moved from mouse events + scrollLeft/Top to Pointer Events with capture, so a single-finger touch drag also pans. Pointer capture is only claimed once real drag movement crosses a small threshold - claiming it on every pointerdown would redirect that pointer's click to the map container instead of whatever was actually pressed (a seat, a section, a zoom button), which would silently break every click-driven interaction on the map. - Section.tsx's zoom-to-section-on-click effect now sets the new pan/zoom state directly instead of calling scrollTo() on the old scroll container.
Every view change (button zoom, reset, and zooming into a section on click) animated over the same flat 200ms - fine for a small button nudge, but a jarring snap for the much bigger jump from the overview to 8x zoom on one section. Add a transition duration alongside zoom/pan in the store (setView now takes it as a third argument) so each caller can pick its own pace: 200ms for discrete small jumps (buttons, reset), 650ms for section focus. VenueMap also switches from a linear ease-out to a cubic-bezier ease-out curve for a visibly smoother deceleration.
Clicking a section always zoomed to a flat 8x, which overshot for larger sections - part of the section ended up cropped off-screen instead of the whole thing being visible. Compute the zoom from the section's own seat bounding box (padded a bit so seats and the label aren't flush against the screen edge) via the same fit-to-viewport math already used for the venue-level reset view, so bigger sections zoom in less and smaller ones zoom in more. While reworking that effect, also fix the pan calculation to account for the section's own "explode" offset (the small outward nudge applied while it's active) - previously omitted, which left the focused section off-center by that offset.
pnpm start now runs vite preview, serving the dist/ output from pnpm build - previously the only way to run a production build locally was the less-discoverable pnpm preview.
…ng-Map into develop
Rounding seat x/y to whole pixels turned the circular row arcs into a visible zig-zag, since adjacent seats are only ~3-4 units apart - about one seat-box width. Rounding to 2 decimals keeps the arcs smooth while still keeping the generated file readable.
Adds a deterministic best-seats solver (view- or price-priority, strictly-ordered tiebreaks) and a sidebar finder that runs it and selects/focuses the winning block, so a group no longer has to hand-pick seats one at a time.
Seats can now be genuinely held rather than just statically flagged: selecting a seat starts a 5-minute checkout deadline, venue.json's sample `held` seats get real staggered expiries instead of never releasing, and a BroadcastChannel-based protocol shares holds and sales across tabs of the same browser (with a deterministic tie-break for simultaneous picks, and a no-op fallback when the channel is unavailable). Status derivation moves out of Seat.tsx into a single pure resolver, which also fixes two bugs along the way: seats re-rendered on every zoom tick instead of only when the label threshold was crossed, and the price in every seat's aria-label read the raw tier number instead of its dollar amount.
Raises the coverage regression floor in vite.config.ts to match the actual numbers after the two features' near-100%-covered utility modules landed, and updates the README, engineering notes, and the UI/UX flow reference so they describe current behavior instead of the now-stale "held/reserved never expire, no live-update mechanism" gap the flow doc used to call out.
Section.tsx always fit the whole section's bounding box on activation, so viewing a past booking or a best-seats result opened the right section but framed all ~1,500 seats instead of the handful that actually mattered. Generalizes the fix into one store field, mapFocusSeatIds, that selectSeatBlock and viewBooking both set and setActiveSection clears, so a manual section click still fits the whole section as before.
…loating selection toolbar Moves the "Seat Status" legend out of the sidebar into an always-visible card in the map's top-right corner, freeing sidebar space and matching how real ticketing UIs keep the map's own chrome self-contained. Adds a floating black toolbar that appears above the map whenever any seat is selected: live seat count, running total, a mirror of the checkout countdown (most useful on mobile, where the sidebar - and its own timer - starts hidden), and a one-click Remove to clear the cart. Raises the coverage floor to match the new fully-tested components.
Every existing holdChannel/useHoldSync test drives the protocol through a fake in-memory bus, since jsdom has no BroadcastChannel at all. That proves the protocol logic is correct but never proves the real transport actually delivers a message from one tab to another. Runs in Node's own test environment instead (which does implement BroadcastChannel) so two independent createHoldChannel instances can stand in for two real browser tabs with no fake in the loop.
…tial notes only Cuts multi-line "why" prose down to at most one short line, and only where it explains a genuinely non-obvious constraint or invariant (e.g. the pruneHolds reference-identity guarantee the perf story depends on, the resolver's held-before-selected fail-safe ordering). Comment-only change - no logic, JSX, or type changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.